﻿using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
using System.Net.Http;
using System.Threading.Tasks;

/// <summary>
/// 微信小程序支付下单工具类
/// </summary>
public class WeChatPayHelper
{
    // 微信支付配置
    private readonly string _appId; // 小程序AppId
    private readonly string _mchId; // 商户号
    private readonly string _apiKey; // API密钥
    private readonly string _unifiedOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    private readonly string _notifyUrl; // 支付结果通知地址

    public WeChatPayHelper(string appId, string mchId, string apiKey, string notifyUrl)
    {
        _appId = appId;
        _mchId = mchId;
        _apiKey = apiKey;
        _notifyUrl = notifyUrl;
    }

    /// <summary>
    /// 微信小程序统一下单
    /// </summary>
    /// <param name="orderNo">商户订单号</param>
    /// <param name="totalFee">订单金额(分)</param>
    /// <param name="body">商品描述</param>
    /// <param name="openId">用户OpenId</param>
    /// <returns>支付参数</returns>
    public async Task<WeChatPayResponse> MiniProgramUnifiedOrder(string orderNo, int totalFee, string body, string openId)
    {
        // 组装请求参数
        var parameters = new SortedDictionary<string, string>
        {
            {"appid", _appId},
            {"mch_id", _mchId},
            {"nonce_str", GenerateNonceStr()},
            {"body", body},
            {"out_trade_no", orderNo},
            {"total_fee", totalFee.ToString()},
            {"spbill_create_ip", GetClientIp()},
            {"notify_url", _notifyUrl},
            {"trade_type", "JSAPI"}, // 小程序支付固定为JSAPI
            {"openid", openId}
        };

        // 生成签名
        parameters.Add("sign", GenerateSign(parameters));

        // 转换为XML
        var xmlData = ConvertToXml(parameters);

        // 发送请求
        var responseXml = await PostXml(_unifiedOrderUrl, xmlData);
        return ParseXmlResponse(responseXml);
    }

    /// <summary>
    /// 生成随机字符串
    /// </summary>
    private string GenerateNonceStr()
    {
        return Guid.NewGuid().ToString().Replace("-", "");
    }

    /// <summary>
    /// 生成签名
    /// </summary>
    public string GenerateSign(SortedDictionary<string, string> parameters)
    {
        var sb = new StringBuilder();
        foreach (var param in parameters)
        {
            if (!string.IsNullOrEmpty(param.Value) && param.Key != "sign")
            {
                sb.Append($"{param.Key}={param.Value}&");
            }
        }
        sb.Append($"key={_apiKey}");

        using (var md5 = MD5.Create())
        {
            var bytes = Encoding.UTF8.GetBytes(sb.ToString());
            var hash = md5.ComputeHash(bytes);
            return BitConverter.ToString(hash).Replace("-", "").ToUpper();
        }
    }

    /// <summary>
    /// 转换为XML格式
    /// </summary>
    private string ConvertToXml(SortedDictionary<string, string> parameters)
    {
        var xml = new XmlDocument();
        var root = xml.CreateElement("xml");
        xml.AppendChild(root);

        foreach (var param in parameters)
        {
            var element = xml.CreateElement(param.Key);
            element.InnerText = param.Value;
            root.AppendChild(element);
        }

        return xml.OuterXml;
    }

    /// <summary>
    /// 发送XML请求
    /// </summary>
    private async Task<string> PostXml(string url, string xmlData)
    {
        using (var httpClient = new HttpClient())
        {
            var content = new StringContent(xmlData, Encoding.UTF8, "text/xml");
            var response = await httpClient.PostAsync(url, content);
            return await response.Content.ReadAsStringAsync();
        }
    }

    /// <summary>
    /// 解析XML响应
    /// </summary>
    private WeChatPayResponse ParseXmlResponse(string xml)
    {
        var doc = new XmlDocument();
        doc.LoadXml(xml);
        var root = doc.SelectSingleNode("xml");

        return new WeChatPayResponse
        {
            ReturnCode = root.SelectSingleNode("return_code")?.InnerText,
            ReturnMsg = root.SelectSingleNode("return_msg")?.InnerText,
            ResultCode = root.SelectSingleNode("result_code")?.InnerText,
            ErrCode = root.SelectSingleNode("err_code")?.InnerText,
            ErrCodeDes = root.SelectSingleNode("err_code_des")?.InnerText,
            PrepayId = root.SelectSingleNode("prepay_id")?.InnerText,
            NonceStr = root.SelectSingleNode("nonce_str")?.InnerText
        };
    }

    /// <summary>
    /// 获取客户端IP
    /// </summary>
    private string GetClientIp()
    {
        // 实际项目中需根据环境获取真实IP
        return "127.0.0.1";
    }
}

/// <summary>
/// 微信支付响应实体
/// </summary>
public class WeChatPayResponse
{
    public string ReturnCode { get; set; } // 返回状态码
    public string ReturnMsg { get; set; } // 返回信息
    public string ResultCode { get; set; } // 业务结果
    public string ErrCode { get; set; } // 错误代码
    public string ErrCodeDes { get; set; } // 错误代码描述
    public string PrepayId { get; set; } // 预支付交易会话标识
    public string NonceStr { get; set; } // 随机字符串
}
